package com.hushan.elevator.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdcardUtil;
import com.hushan.elevator.model.*;
import com.hushan.elevator.security.SecurityUtils;
import com.hushan.elevator.service.*;
import com.hushan.elevator.utils.Result;
import com.hushan.elevator.utils.ResultCode;
import com.hushan.elevator.vo.DeviceMntAddVo;
import com.hushan.elevator.vo.MntInfoTableVo;
import com.hushan.elevator.vo.MntPersonTableVo;
import com.hushan.elevator.vo.UserDataVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import jakarta.validation.Valid;
import org.springframework.data.domain.PageRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/mnt")
@Validated
public class MntController {
    private final MntPersonService mntPersonService;
    private final DeptService deptService;
    private final DeviceInfoService deviceInfoService;
    private final DeviceMntService deviceMntService;
    private final UserService userService;
    public MntController(MntPersonService mntPersonService, DeptService deptService, DeviceInfoService deviceInfoService, DeviceMntService deviceMntService, UserService userService) {
        this.mntPersonService = mntPersonService;
        this.deptService = deptService;
        this.deviceInfoService = deviceInfoService;
        this.deviceMntService = deviceMntService;
        this.userService = userService;
    }

    @Operation(summary = "获取全部人员", description = "获取本单位所有维修人员的信息列表")
    @GetMapping("/persons")
    public Result getAllPersons() {
        User requestUser = SecurityUtils.getUser();
        Department requesterDept = deptService.findDeptByUserId(requestUser.getUserId());

        List<Department> list = deptService.findChildByDeptId(requesterDept.getDeptId());

        list.add(requesterDept);

        List<MntPersonTableVo> rst = new ArrayList<>();
        for (Department item : list) {
            List<MntPersonTableVo> mntPersonByDept = getMntPersonByDept(item);
            rst.addAll(mntPersonByDept);
        }
        return new Result(ResultCode.SUCCESS, rst);
    }

    @Operation(summary = "根据维修人员Id获取详细人员信息", description = "根据指定的人员ID获取单个维修人员的详细信息")
    @GetMapping("/persons/{id}")
    public Result getPersonById(@PathVariable("id") int id) {
        boolean detectAuthorize = mntPersonService.detectAuthorize(id);
        if (!detectAuthorize) {
            return Result.UN_AUTHORISE();
        }
        return new Result(ResultCode.SUCCESS, mntPersonService.getPersonById(id));
    }

    @Operation(summary = "添加人员信息", description = "根据提供的新的人员信息来添加人员记录")
    @PostMapping("/persons")
    public Result addPerson(@RequestBody MntPerson personAdd) {
        boolean valid18 = IdcardUtil.isValidCard(personAdd.getIdCard());
        if (!valid18) {
            return new Result(ResultCode.FAIL,"身份证号不符合规范");
        }
        boolean isValid = Validator.isMobile(personAdd.getTelNumb());
        if (!isValid) {
            return new Result(ResultCode.FAIL,"手机号码不符合规范");
        }

        User requestUser = SecurityUtils.getUser();
        // detect has or not this dept authority
        boolean detectAuthorize = deptService.findUserPermissionForDept(requestUser, personAdd.getDeptId());
        if (!detectAuthorize) {
            return Result.UN_AUTHORISE();
        }
        personAdd.setCreatedBy(requestUser.getUserId());
        mntPersonService.addPerson(personAdd);
        return new Result(ResultCode.SUCCESS);
    }

    @Operation(summary = "根据人员Id修改人员信息", description = "根据提供的人员ID和新的人员信息来更新人员记录")
    @PutMapping("/persons/{id}")
    public Result updatePerson(@PathVariable("id") int id, @RequestBody MntPerson person) {
        if (id != person.getMntUserId()) {
            return Result.FAIL();
        }
        boolean detectAuthorize = mntPersonService.detectAuthorize(id);
        if (!detectAuthorize) {
            return Result.UN_AUTHORISE();
        }
        mntPersonService.updatePerson(person);
        return new Result(ResultCode.SUCCESS);
    }

    @Operation(summary = "根据人员Id删除人员", description = "根据指定的人员ID删除对应的维修人员记录")
    @DeleteMapping("/persons/{id}")
    public Result deletePerson(@PathVariable("id") int id) {
        boolean detectAuthorize = mntPersonService.detectAuthorize(id);
        if (!detectAuthorize) {
            return Result.UN_AUTHORISE();
        }
        try {
            mntPersonService.deleteById(id);
        } catch (Exception e) {
            return new Result(ResultCode.FAIL, "维保人员存在需要维保的设备，请交接后再重试");
        }
        return new Result(ResultCode.SUCCESS);
    }

    @Operation(summary = "根据人员Id列表删除维保人员",
            description = "根据维保人员id列表删除维保人员，查询每个维保人员是否能够被删除")
    @DeleteMapping("")
    public Result deletePerson(@RequestBody List<Integer> ids) {
        try {
            for (Integer id : ids) {
                boolean detectAuthorize = mntPersonService.detectAuthorize(id);
                if (!detectAuthorize) {
                    return Result.UN_AUTHORISE();
                }
                mntPersonService.deleteById(id);
            }
        } catch (Exception e) {
            return new Result(ResultCode.FAIL, "维保人员存在需要维保的设备，请交接后再重试");
        }
        return new Result(ResultCode.SUCCESS);
    }

    @Operation(summary = "获取某单位下的维保人员", description = "通过校验后，根据传入的id获取某单位下的维保人员")
    @GetMapping("/persons/dept/{id}")
    public Result getPersonByDeptId(@PathVariable("id") int id) {
        boolean detectAuthorize = deptService.findUserPermissionForDept(SecurityUtils.getUser(),id);
        if (!detectAuthorize) {
            return Result.UN_AUTHORISE();
        }
        return new Result(ResultCode.SUCCESS, mntPersonService.getPersonsByDeptId(id));
    }


    @Operation(summary = "获取某单位下包含子单位的维保人员", description = "通过校验后，根据传入的id获取某单位下包含下属子单位的维保人员")
    @GetMapping("/persons/dept/c/{id}")
    public Result getChildPersonByDeptId(@PathVariable("id") int id) {
        boolean permission = deptService.findUserPermissionForDept(SecurityUtils.getUser(), id);
        if (!permission) {
            return Result.UN_AUTHORISE();
        }
        List<Department> childDeptList = deptService.findChildByDeptId(id);
        childDeptList.add(deptService.findDeptById(id));

        List<MntPersonTableVo> rst = new ArrayList<>();
        for (Department item : childDeptList) {
            List<MntPersonTableVo> mntPersonByDept = getMntPersonByDept(item);
            rst.addAll(mntPersonByDept);
        }
        return new Result(ResultCode.SUCCESS, rst);
    }

    public List<MntPersonTableVo> getMntPersonByDept(Department dept) {
        List<MntPersonTableVo> rst = new ArrayList<>();
        List<MntPerson> mntPersonList = mntPersonService.getPersonsByDeptId(dept.getDeptId());
        for (MntPerson person : mntPersonList) {

            MntPersonTableVo vo = new MntPersonTableVo();
            BeanUtil.copyProperties(person, vo);
            vo.setDept(dept.getName());
            rst.add(vo);
        }
        return rst;
    }


    @Operation(summary = "获取当前用户的所有设备的最新维保信息", description = "获取当前用户的所有设备的最新维保信息" +
            "返回当前时间、最新的维保信息")
    @GetMapping("/device/info")
    public Result getMntInfo() {
        User requestUser = SecurityUtils.getUser();
        Department requesterDept = deptService.findDeptByUserId(requestUser.getUserId());
        List<DeviceInfo> deviceByDeptId = deviceInfoService.findChildDeptDeviceByDeptId(requesterDept.getDeptId());
        List<DeviceMnt> rst = new ArrayList<>();
        for (DeviceInfo d:deviceByDeptId){
            DeviceMnt latestRecord = deviceMntService.findLatestRecord(d.getDeviceId());
            rst.add(latestRecord);
        }
        return new Result(ResultCode.SUCCESS, rst);
    }

    @Operation(summary = "获取当前用户的所有设备的维保详情信息", description = "获取当前用户的所有设备的维保详情信息")
    @GetMapping("/device/detail")
    public Result getMntDetailInfo( @Parameter(description = "页码") @RequestParam(value="p",defaultValue = "1") Integer page,
                                    @Parameter(description = "每页数量") @RequestParam(value="s",defaultValue = "10") Integer size) {
        User requestUser = SecurityUtils.getUser();
        Department requesterDept = deptService.findDeptByUserId(requestUser.getUserId());
        PageRequest pageRequest = PageRequest.of(page, size);
        List<DeviceInfo> deviceByDeptId = deviceInfoService.findChildDeptDeviceByDeptId(requesterDept.getDeptId(),pageRequest);
        List<MntInfoTableVo> rst = new ArrayList<>();
        for (DeviceInfo d:deviceByDeptId){
            DeviceMnt latestRecord = deviceMntService.findLatestRecord(d.getDeviceId());
            MntPerson mntPerson = mntPersonService.findByDevice(d.getDeviceId());
            MntInfoTableVo mntInfoTableVo = new MntInfoTableVo();
            BeanUtil.copyProperties(latestRecord, mntInfoTableVo);
            if (mntPerson!=null){
                mntInfoTableVo.setMntPersonName(mntPerson.getName());
                mntInfoTableVo.setMntPersonCompany(mntPerson.getCompany());
                mntInfoTableVo.setMntPersonTel(mntPerson.getTelNumb());
                mntInfoTableVo.setMntPersonId(mntPerson.getMntUserId());
            }
            mntInfoTableVo.setAdmin(d.getCreatedBy());
            mntInfoTableVo.setAdminName(userService.findUserByUserId(d.getCreatedBy()).getTitle());
            mntInfoTableVo.setDeptId(requesterDept.getDeptId());
            mntInfoTableVo.setDeptName(requesterDept.getName());
            mntInfoTableVo.setDeviceName(d.getDeviceName());
            mntInfoTableVo.setDeviceSerial(d.getSerialNumber());
            mntInfoTableVo.setDeviceStatus(d.getStatus());
            rst.add(mntInfoTableVo);
        }
        return new Result(ResultCode.SUCCESS, rst);
    }

    @Operation(summary = "新增设备维保记录", description = "新增设备维保记录")
    @PostMapping("/device/{id}")
    public Result addMntRecord(@PathVariable("id") int deviceId,@RequestBody @Valid DeviceMntAddVo deviceMnt) {
        DeviceMnt mnt = new DeviceMnt();
        BeanUtil.copyProperties(deviceMnt,mnt);
        mnt.setMntUser(deviceMnt.getMntPersonId());
        mnt.setDeviceId(deviceId);
        deviceMntService.addDeviceMnt(mnt);
        return new Result(ResultCode.SUCCESS);
    }
}
